/**
 * Created by zhangqi on 2015/4/16.
 * 调用一个简单的下单菜单的例子
 * html部分：
 * 先新建一个div (id可以随意，但是class要有一个固定的dayhr_drop_select):   <div id="xxxxxxxx" class="dayhr_drop_select"></div>
 * js部分：
 *  var drop = new dayhrDropSelect({
        id: "download_excel_templates",
        width: 180,
        maxHeight: 250,
        data: [{id:"id1", name:"选项一"},{id:"id2", name:"选项二"}],
        name: "modelId",
        onSelected:function(oSelect, type){}  oSelect：选择之后的节点数据，type:是手动还是从代码自动触发的（"click","codeAuto"）
    });
 drop.getValue()
 */

    //tree组件
    require("./dayhrDropSelect.css")
    require("../zTree/zTreeStyle/zTreeStyle.css");
    require("../zTree/jquery.ztree.all.min");

    /**
     * 移除数组某个元素
     */
    Array.prototype.removeElement = function (ele) {
        var arr = this;
        for (var i = 0, len = arr.length; i < len; i++) {
            if (arr[i] == ele) {
                arr.splice(i, 1);
                return;
            }
        }
    }

    var dayhrDropSelect = function(){
        this.init.apply(this,arguments);
    }
    dayhrDropSelect.prototype = {
        selectedId:"",
        selectedVal:"",
        options:{
            id:"dayhr_drop_select"  //绑定tree的节点
            ,width:180 //宽度
            ,maxHeight:250 //最大下拉高度
            ,data:[]  //加载的数据
            ,name:"dayhr_drop_select_name"
            ,onSelected:undefined  // function类型，下拉树选中之后的回调
            ,isEdit:true //是否可以编辑
            ,isAllowOther:false //是否允许输入其他值
            ,placeholder:""
        },
        init:function(options){
            var t = this;
            t.options = $.extend({},t.options,options);
            t.element = $("#"+ t.options.id);
            if(!t.element[0]){
                throw new Error("请传正确的id参数");
                return false;
            }
            t.options.data = t.formatData(t.options.data);
            t.renderDom();
        },
        //初始化dom
        renderDom:function(){
            var t = this;
            var _html = '' +
                '<input type="text" autocomplete="off" class="dayhr_drop_select_input" style="width:'+ (t.options.width-5-31)+'px;" placeholder="'+t.options.placeholder+'">' +
                '<input type="hidden" name="'+ t.options.name+'">'+
                '<div class="dayhr_drop_select_ico"><span style="display: block">▼</span><span>▲</span></div>' +
                '<div class="dayhr_drop_select_disable" style="'+ (t.options.isEdit?'display:none':'display:block')+'"></div>'+
                '<ul class="dayhr_drop_select_tree ztree" id="tree-'+ t.options.id+'" style="width:'+ (t.options.width-10)+'px;max-height:'+ t.options.maxHeight+'px;"><li>no data</li></ul>'+
                '<ul class="dayhr_drop_select_search_tree ztree" id="tree-search-'+ t.options.id+'" style="width:'+ (t.options.width-10)+'px;max-height:'+ t.options.maxHeight+'px;"><li>no data</li></ul>';
            t.element.html(_html);
            t.element.css({width: t.options.width+"px"});
            t.$showInput = t.element.find(".dayhr_drop_select_input");
            t.$hiddenInput = t.element.find("input[type='hidden']");
            t.initTree();
            t.bindEvent(); //绑定事件
        },
        //格式化数据
        formatData:function(aData){
            if(!aData.length){
                return [];
            }
            var setData = function(arr){
                var aTemp = [];
                for(var i=0;i<arr.length;i++){
                    if(arr[i].tip){
                        arr[i].fullName = arr[i].name + "（" +arr[i].tip + "）";
                    }else{
                        arr[i].fullName = arr[i].name;
                    }
                    if(arr[i].children && arr[i].children.length){
                        arr[i].children = setData(arr[i].children);
                    }
                    aTemp.push(arr[i]);
                }
                return aTemp;
            }
            return setData(aData);
        },
        //初始化树
        initTree:function(){
            var t = this;
            t.setting = {
                view:{showIcon:false,showTitle:true,fontCss:function(treeId, treeNode){
                    if(treeNode.chkDisabled){
                        return {opacity:"0.6"};
                    }
                }},
                data: {
                    key: {
                        title: "fullName"
                    }
                },
                callback:{
                    onClick:function(event, treeId, treeNode){
                        //单选的情况
                        if(treeNode.chkDisabled){
                            return false;
                        }
                        t.selectedId= treeNode.id; //key
                        t.selectedVal = treeNode.name; //value
                        t.$resultTree.hide();
                        t.$searchTree.hide();
                        t.element.removeClass("openstatus");
                        //如果不是主树，单独设置主树的选中状态
                        if(treeId.indexOf("tree-search") != -1){
                            var aNodes = t.ztreeResultObj.transformToArray(t.ztreeResultObj.getNodes());
                            for(var i=0;i<aNodes.length;i++){
                                if(aNodes[i].id == treeNode.id){
                                    t.ztreeResultObj.selectNode(aNodes[i]);
                                    break;
                                }
                            }
                        }
                        //传送父树的ConditionBean
                        var oSelect = {
                            key:t.options.name,  //表单项的name
                            value:treeNode.id,  //表单项的选值
                            node:treeNode //节点对象
                        };
                        typeof t.options.onSelected == "function" && t.options.onSelected(oSelect,"click");  //下拉树选中之后的回调,手动触发的
                        t.$showInput.val(t.selectedVal);
                        t.$hiddenInput.val(t.selectedId);
                    }
                }
            };
            var zNodes;
            if($.isArray(t.options.data) && t.options.data.length){
                zNodes = t.options.data;
            }else if($.isPlainObject(t.options.data) && !$.isEmptyObject(t.options.data)){
                zNodes = [t.options.data];
            }else{
                zNodes = [{id:"none",name:"no data...",chkDisabled:true}];
            }
            $.fn.zTree.init($("#tree-"+t.options.id), t.setting, zNodes);
            t.ztreeResultObj = $.fn.zTree.getZTreeObj("tree-"+t.options.id);//缓存起树
        },
        /**
         * 取消主树节点的选中,刷新树即可
         * */
        unSeletedResultTree:function(){
            var t = this;
            t.ztreeResultObj.refresh();
        },
        /**
         * 清除所有结果，包括（显示文本框，隐藏文本框，树选中）
         * */
        clearAll:function(){
            var t = this;
            t.$showInput.val("");
            t.$hiddenInput.val("");
            t.unSeletedResultTree();
        },
        /**
         * 绑定焦点事件
         * */
        bindEvent:function(){
            var t = this;
            t.$resultTree = t.element.find(".dayhr_drop_select_tree");
            t.$searchTree = t.element.find(".dayhr_drop_select_search_tree");

            t.element.off().on("click",".dayhr_drop_select_ico",function(event){
                $(".dayhr_drop_select").find(".ztree").each(function(){
                    if($(this).parent(".dayhr_drop_select").attr("id") != t.element.attr("id")){
                        $(this).parent(".dayhr_drop_select").removeClass("openstatus");
                        $(this).hide();
                    }
                });
                if(t.element.hasClass("openstatus")){
                    t.element.removeClass("openstatus");
                    t.$resultTree.hide(); //隐藏两棵树
                    t.$searchTree.hide();
                }else{
                    t.element.addClass("openstatus");
                    t.$resultTree.show(); //只显示主树
                }
                event.stopPropagation();
            });
            //两棵树的显示隐藏
            $(document).click(function(event){
                if(!$(event.target).closest("#"+t.options.id).length){
                    t.element.removeClass("openstatus");
                    t.$resultTree.hide();
                    t.$searchTree.hide();
                }
            });
            //鼠标离开输入框要做的事
            t.element.on("blur",".dayhr_drop_select_input",function(){
                //执行一次查询，如果文本框中的结果在树中不存在就清空选择结果
                var aTreeNodes = t.ztreeResultObj.getNodes();
                if(aTreeNodes && aTreeNodes.length){
                    var _val = t.$showInput.val();
                    var aNodes = t.ztreeResultObj.transformToArray(aTreeNodes);
                    if(_val && aNodes.length){
                        var isInNodes = false; //文本框的结果是否在树种
                        for(var i=0;i<aNodes.length;i++){
                            if(aNodes[i].name == _val){
                                isInNodes = true;
                                //如果刚好主树种有匹配，并且匹配值是可选的，那么设置成这个值
                                if(!aNodes[i].chkDisabled){
                                    t.ztreeResultObj.selectNode(aNodes[i]);
                                    t.$hiddenInput.val(aNodes[i].id);
                                    t.selectedId = aNodes[i].id;
                                }else{
                                    t.clearAll();
                                }
                                break;
                            }
                        }
                        //如果没有匹配，或者文本框为空的时候就清空值，并取消主树选中
                        if(!isInNodes){
                            //如果设置了允许其他值，并且值没有匹配上就让其他值生效
                            if(t.options.isAllowOther){
                                t.$showInput.val(_val);
                                t.$hiddenInput.val(_val);
                            }else{
                                t.clearAll();
                            }
                        }
                        if(t.$showInput.val() == ""){
                            t.clearAll();
                        }
                    }
                }
            });
            //绑定搜索事件
            t.bindSearchEvent();
        },
        /**
         * 绑定鼠标输入搜索事件
         * */
        bindSearchEvent:function(){
            var t = this;
            var timer = null;
            t.element.on("keyup",".dayhr_drop_select_input",function(){
                var that = this;
                clearTimeout(timer);
                timer = setTimeout(function(){
                    t.doSearch();
                },300);
            });
        },
        /**
         * 执行搜索
         * */
        doSearch:function(){
            var t = this;
            var sVal = t.$showInput.val();
            if(!sVal){
                t.$hiddenInput.val(""); //清空显示结果
                t.selectedId = ""; //清空结果
                return;
            }
            var aNodes = t.ztreeResultObj.transformToArray(t.ztreeResultObj.getNodes());
            //如果没有树结果
            if(!aNodes.length){
                t.$showInput.val("");
                t.$hiddenInput.val("");
                return;
            }
            var aNewNodes = [];
            if(aNodes.length){
                for(var i=0;i<aNodes.length;i++){
                    if(aNodes[i].name.indexOf(sVal) != -1 && !aNodes[i].chkDisabled){  //搜索的时候过滤掉为禁用状态的节点，如果选择组织员工的时候，只有员工节点才能被搜索出来
                        var oTemp = {
                            id:aNodes[i].id,
                            name:aNodes[i].name,
                            chkDisabled:aNodes[i].chkDisabled,
                            fullName:aNodes[i].tip?(aNodes[i] + "（"+aNodes[i].tip+"）"):aNodes[i].name
                        };
                        aNewNodes.push(oTemp);
                    }
                }
                if(aNewNodes.length){
                    $.fn.zTree.init($("#tree-search-"+t.options.id), t.setting, aNewNodes);
                    t.ztreeSearchObj = $.fn.zTree.getZTreeObj("tree-search-"+t.options.id);//缓存起树
                    t.$resultTree.hide();
                    t.$searchTree.show();
                    t.element.addClass("openstatus");
                }else{
                    t.$searchTree.hide();
                }
            }
        },
        //获取值
        getValue:function(){
            return this.selectedId||"";
        },
        /*
         * 获取选中的结点的对象
         * "{"name":"分部2","id":"8","children":null,"condition":{"value":"like '0001!0008!%'","key":"org_id_queue","equal":false,"childCondition":null,"and":true,"joinBean":null,"joinAlias":null},"parentId":null,"chkDisabled":false,"open":true,"isRefreshTableStyle":false,"tip":null,"baseName":null,"baseId":null,"baseCode":null,"baseCorpId":null,"fullName":"分部2"}"
         */
        getObjValue:function () {
            var t = this;
            var oResult = null;
            if(t.getValue() && t.options.data.length){
                for(var i=0;i<t.options.data.length;i++){
                    if(t.getValue() == t.options.data[i].id){
                        oResult = t.options.data[i];
                    }
                }
            }
            return oResult;
        },
        //获取显示值
        getShowValue:function(){
            return this.selectedVal||"";
        },
        //设置值
        setValue:function(val){
            var t = this;
            var isHasSelected = false; //是否成功匹配选中
            if(!val){
                t.$showInput.val("");
                t.$hiddenInput.val("");
                return;
            }
            var treeObj = $.fn.zTree.getZTreeObj("tree-"+t.options.id);
            var nodes = treeObj.getNodes();
            function setSelectedNode(aNodes){
                if(aNodes.length){
                    for(var i=0;i<aNodes.length;i++){
                        if(aNodes[i].id == val || aNodes[i].name == val){ //选中匹配,用或的关系来处理，要保证树的每个name唯一，因为后端有时候不好同时传id和name过来
                            isHasSelected = true;
                            treeObj.selectNode(aNodes[i]);
                            t.$showInput.val(aNodes[i].name);
                            t.$hiddenInput.val(aNodes[i].id);

                            t.selectedId= aNodes[i].id; //key
                            t.selectedVal = aNodes[i].name; //value

                            //传送父树的ConditionBean,模拟click选中后的回调
                            var oSelect = {
                                key:t.options.name,  //表单项的name
                                value:aNodes[i].id,  //表单项的选值
                                node:aNodes[i] //节点对象
                            };
                            typeof t.options.onSelected == "function" && t.options.onSelected(oSelect,"codeAuto");  //下拉树选中之后的回调，代码自动触发的
                        }
                        if(aNodes[i].children && aNodes[i].children.length){
                            setSelectedNode(aNodes[i].children);
                        }
                    }
                }
            }
            setSelectedNode(nodes);
            //如果没成功匹配选中就放开选择框，并且清空值
            if(!isHasSelected){
                if(t.options.isAllowOther){
                    t.$showInput.val(val);
                    t.$hiddenInput.val(val);
                }else{
                    t.$showInput.val("");
                    t.$hiddenInput.val("");
                    t.element.find(".dayhr_drop_select_disable").hide();
                }
            }
        },
        //更新待选值
        updateTreeJson:function(arr){
            if(!arr || !arr.length){
                arr = [{id:"none",name:"no data...",chkDisabled:true}];
            }
            var t = this;
            arr = t.formatData(arr);
            var treeObj = $.fn.zTree.getZTreeObj("tree-"+t.options.id);
            treeObj.destroy();//销毁树
            t.$showInput.val("");
            t.$hiddenInput.val("");
            $.fn.zTree.init($("#tree-"+t.options.id), t.setting, arr); //重新初始化树
            t.ztreeResultObj = $.fn.zTree.getZTreeObj("tree-"+t.options.id);//重新缓存起树
        },
        /**
         * 设置可用状态
         * @status true/false (不可用/可用)
         * */
         setDisabled:function(status){
            var t = this;
            if(status){
                t.element.find(".dayhr_drop_select_disable").show();
            }else{
                t.element.find(".dayhr_drop_select_disable").hide();
            }
         }
     }

    module.exports = dayhrDropSelect;

